const Client = require('ssh2').Client

const fs = require('fs')
const path = require('path')

const yaml = require('js-yaml')
const PUBLISH_CONFIG = yaml.load(fs.readFileSync('publish-config.yaml', 'utf8'))

const archiver = require('archiver')

;(async () => {
  /**** 配置 *****/
  const CONFIG = PUBLISH_CONFIG[process.env.buildMode || 'test']
  /**** 配置 *****/

  /**** 压缩 *****/
  const uploadZipPath = __dirname + '/upload.zip'
  const output = fs.createWriteStream(uploadZipPath)

  const archive = archiver('zip', {
    zlib: { level: 6 }, // Sets the compression level.
  })
  archive.append(fs.createReadStream('../pm2-setup.json'), { name: 'pm2-setup.json' })
  archive.pipe(output)
  archive.directory(path.resolve('../', 'patches'), 'patches')
  archive.directory(path.resolve('.', CONFIG.filePath), CONFIG.distName || '')
  await archive.finalize()

  /**** 连接 *****/
  const conn = new Client()
  conn.connect({
    host: CONFIG.ip,
    port: 22,
    username: CONFIG.username,
    password: CONFIG.password,
  })
  await new Promise((resolve) => conn.on('ready', resolve))
  await new Promise((resolve, reject) => {
    conn.exec(
      `rm -rf  ${path2Dir(CONFIG.targetPath)} && mkdir -p ${path2Dir(CONFIG.targetPath)}`,
      function (err, stream) {
        if (err) return reject(err)
        stream.pipe(process.stdout)
        stream.on('close', () => {
          console.log('=======清除完毕=======')
          resolve()
        })
      },
    )
  })
  const sftp = await new Promise((resolve, reject) => conn.sftp((err, sftp) => (err ? reject(err) : resolve(sftp))))
  await new Promise((resolve, reject) =>
    sftp.fastPut(path.resolve('.', 'upload.zip'), path.posix.join(CONFIG.targetPath, 'upload.zip'), function (err) {
      return err ? reject(err) : resolve()
    }),
  )
  await new Promise((resolve, reject) => {
    conn.exec(
      `unzip -o ${path.posix.join(CONFIG.targetPath, 'upload.zip')} -d ${path2Dir(CONFIG.targetPath)}`,
      function (err, stream) {
        if (err) return reject(err)
        stream.pipe(process.stdout)
        stream.on('close', () => {
          console.log('=======上传完毕=======')
          resolve()
        })
      },
    )
  })
  await new Promise((resolve, reject) => {
    const isTest = process.env.buildMode === 'test'
    const nodePath = isTest ? `node-v16.19.1-linux-x64` : 'local'
    const pm2Path = `/usr/${nodePath}/bin/pm2`
    const yarnPath = `/usr/${nodePath}/bin/yarn`
    conn.exec(
      `cd ${path2Dir(CONFIG.targetPath)}/server && ${yarnPath} --ignore-engines  && ${pm2Path} start ../pm2-setup.json`,
      function (err, stream) {
        if (err) return reject(err)
        stream.pipe(process.stdout)
        stream.on('close', () => {
          console.log('=======启动完毕=======')
          resolve()
        })
      },
    )
  })
  conn.end()
})()

function path2Dir(path) {
  return path.indexOf('/', path.length) > -1 ? path + '/' : path
}
